//
// DashboardPlugin.cs
//
// Copyright (C) 2007 Fredrik Hedberg <fredrik@avafan.com>
// Copyright (C) 2008 Lukas Lipka <lukaslipka@gmail.com>
//

using System;
using System.Runtime.InteropServices;

using Mono.Unix;

using Dashboard;

using Banshee.Base;
using Banshee.Plugins;
using Banshee.MediaEngine;

public static class PluginModuleEntry {

	public static Type [] GetTypes()
	{
		return new Type [] {
			typeof(Banshee.Plugins.Dashboard.DashboardPlugin)
		};
	}
}

namespace Banshee.Plugins.Dashboard {

	public class DashboardPlugin : Plugin {

		private Connection connection = null;
		private string clue_message_id = null;

		protected override string ConfigurationName { 
			get { return "Dashboard"; } 
		}
		
		public override string DisplayName { 
			get { return "Dashboard"; } 
		}
		
		public override string Description {
			get { 
				return Catalog.GetString("Dashboard automatically displays information " +
							 "relevant to your current activities. This plugin " +
							 "sends clues about what music you are listening to."); 
			}
		}
		
		public override string [] Authors {
			get {
				return new string [] { "Fredrik Hedberg", "Lukas Lipka" };
			}
		}
		
		protected override void PluginInitialize ()
		{
			PlayerEngineCore.EventChanged += OnPlayerEngineEventChanged;
		}
		
		protected override void PluginDispose ()
		{
			PlayerEngineCore.EventChanged -= OnPlayerEngineEventChanged;
		}

		private void OnPlayerEngineEventChanged (object o, PlayerEngineEventArgs args)
                {
			// Only send notifications when we start playing a new song
			if (args.Event != PlayerEngineEvent.StartOfStream)
				return;

			// FIXME: Our client API sucks at handling cases when dashboard
			// is not running and thats the reason the following block of code
			// is in a try block.

			try {
				if (connection == null)
					connection = Connection.Create ();
				
				TrackInfo track = PlayerEngineCore.CurrentTrack;
				
				// FIXME: The window Xid detection sucks, we might consider
				// adding this into our client API.
				
				ClueMessage clue_message = new ClueMessage ();
				clue_message.Path = "/event/media/playing";
				clue_message.Window = (ulong) gdk_x11_drawable_get_xid (InterfaceElements.MainWindow.GdkWindow.Handle);
				
				Clue track_clue = new Clue ("db:media");
				
				track_clue.Properties.Add (new Property ("dc:title", "dc:string", track.Title));
				track_clue.Properties.Add (new Property ("dc:extent", "dc:timespan", track.Duration.ToString ()));
				
				if (!String.IsNullOrEmpty (track.Artist))
					track_clue.Properties.Add (new Property ("db:artist", "dc:string", track.Artist));
				
				if (!String.IsNullOrEmpty (track.Album))
					track_clue.Properties.Add (new Property ("db:album", "dc:string", track.Album));
				
				if (!String.IsNullOrEmpty (track.MimeType))
					track_clue.Properties.Add (new Property ("dc:format", "dc:string", track.MimeType));
				
				if (!String.IsNullOrEmpty (track.CoverArtFileName))
					track_clue.Properties.Add (new Property ("dc:image", "dc:uri", String.Format ("file://{0}", track.CoverArtFileName)));
				
				clue_message.Clues.Add (track_clue);
				
				if (!String.IsNullOrEmpty (clue_message_id))
					clue_message.Replaces = clue_message_id;
				
				clue_message_id = clue_message.Id;
				
				connection.Send (clue_message);
			} catch (Exception e) {
				Console.WriteLine ("Dashboard plugin - Failed to send clue:");
				Console.WriteLine (e);
			}
		}

		[DllImport("libgdk-x11-2.0.so")]
		extern static UIntPtr gdk_x11_drawable_get_xid (IntPtr window);
	}
}
